package engine.logic.walk
{
	import engine.GameData;
	import engine.control.MiniLoadingBar;
	import engine.display.Story.StoryMoveUI;
	import engine.flag.GameDefine;
	import engine.flag.ObjType;
	import engine.flag.PlayerActionFlag;
	import engine.logic.ArrowGuideLogic;
	import engine.logic.walk.Astar.ForbiddenAreaLogic;
	import engine.net.datatype.WString;
	import engine.net.messages.CustomToServerFlag;
	import engine.net.mgr.SystemSender;
	import engine.newUi.FactionAttackLogic;
	import engine.newUi.MakeSnowLogic;
	import engine.newUi.WarfareLogic;
	import engine.scene.SceneManager;
	import engine.scene.player.BasePlayerModel;
	import engine.scene.player.NpcModel;
	import engine.scene.player.PlayerModel;
	import engine.scene.player.RoleModel;
	
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.utils.clearInterval;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;
	
	import newx.StageInfo;
	import newx.com.config.StaticIni;
	
	public class WalkLogic
	{
		private var _stage 				: Stage;
		
		private var _funcs 				: Array;
		
		public static var Fight			: Boolean;
		
		public static var SceneType		:int;
		
		public static var Role			: BasePlayerModel;
		
		private var _moveTimer				:Timer	=	null;
		
		private var _pTimeFlag				:uint	=	0;
		
		private var pTimeFlag				:uint	=	0;
		
		/**加速倍率*/
		private var _magnificationCount	:Number	=	4;
		
		private var _tDelay				:int	=	1;
		
		private var _txt					:TextField=new TextField();
		
		private var _isWalk				:Boolean;
		private var isFightPre				:Boolean	=	false;
		
		private var otherWalkArr				:Array		=	[];
		
		public static  var isShowLoading		:Boolean	=false;
		private var _showTimer				:Timer;
		private var controlNum				:int			=	30;
		
		private var needSpeed				:Boolean	=	false;
		
		private var _isReset				:Boolean	=	false; 
		
		public function WalkLogic()
		{
			_funcs	=	[];
			
			init();
		}
		
		public function set isReset(value:Boolean):void
		{
			_isReset = value;
		}
		
		private function init():void
		{
			_stage 		= 	StageInfo.stage;
			
			_showTimer  = 	new Timer(100);
			_showTimer.addEventListener(TimerEvent.TIMER,onPlay);
			if(_magnificationCount > 1)
			{
				_tDelay		=	int((1000/_stage.frameRate)*(1/_magnificationCount)*.8);
				_moveTimer	=	new Timer(10);
				//					new Timer(int(
				//					(1000/_stage.frameRate)*(1/_magnificationCount)*.8));
			}
			controlNum	=	int(StaticIni.getIniVar("SceneMaxPlayer","num"));
		}
		
		/**加速倍率*/
		public function get magnificationCount():Number
		{
			return _magnificationCount;
		}
		
		/**
		 * @private
		 */
		public function set magnificationCount(value:Number):void
		{
			_magnificationCount = value;
			if(_magnificationCount > 1)
			{
				_tDelay		=	int((1000/_stage.frameRate)*(1/_magnificationCount)*.8);
				if(_moveTimer == null)
				{
					_moveTimer = new Timer(10);
					_moveTimer.start();
				}
			}else
			{
				if(_moveTimer != null)
				{
					_moveTimer.stop();
					_moveTimer = null;
				}
			}
		}
		
		private function addRenderEvent():void
		{
			_isWalk = true;
			
			if(_moveTimer == null)
			{
				if( !_stage.hasEventListener(Event.ENTER_FRAME) )
				{
					_stage.addEventListener(Event.ENTER_FRAME, onWalking);
				}
			}
			else
			{
				if( !_moveTimer.running )
				{
					_pTimeFlag	=	getTimer();
					_stage.addEventListener(Event.ENTER_FRAME, checkEvent);
					_moveTimer.addEventListener(TimerEvent.TIMER,onWalkingEx);
					_moveTimer.start();
				}
			}
		}
		
		private function addOtherRenderEvent():void
		{
			//			if(_moveTimer == null)
			//			{
			_stage.addEventListener(Event.ENTER_FRAME, onOtherWalking);
			//			}
			//			else
			//			{
			//				pTimeFlag	=	getTimer();
			//				_stage.addEventListener(Event.ENTER_FRAME, checkEvent);
			//				otherTime.addEventListener(TimerEvent.TIMER,onWalkingOther);
			//				otherTime.start();
			//			}
		}
		public function get isWalk():Boolean
		{
			return _isWalk;
		}
		
		private function removeRenderEvent():void
		{
			_isWalk = false;
			
			if(_moveTimer == null)
			{
				_stage.removeEventListener(Event.ENTER_FRAME, onWalking);
			}
			else
			{
				_pTimeFlag	=	0;
				_stage.removeEventListener(Event.ENTER_FRAME, checkEvent);
				_moveTimer.stop();
				_moveTimer.removeEventListener(TimerEvent.TIMER,onWalkingEx);
			}
		}
		
		private function removeOtherRenderEvent():void
		{
			//			if(_moveTimer == null)
			//			{
			_stage.removeEventListener(Event.ENTER_FRAME, onOtherWalking);
			//			}
			//			else
			//			{
			//				pTimeFlag	=	0;
			//				_stage.removeEventListener(Event.ENTER_FRAME, checkEvent);
			//				otherTime.stop();
			//				otherTime.removeEventListener(TimerEvent.TIMER,onWalkingOther);
			//			}
		}
		
		private function onWalking(evt : Event):void
		{
			//战斗中不管
			//			if( Fight ) return;
			//跑动
			if(_funcs.length!=0)
			{
				for each(var func : Function in _funcs)
				{
					//移动
					func.call();
				}
			}
			
			if(_funcs.length==0 || needSpeed == false) _stage.removeEventListener(Event.ENTER_FRAME, onWalking);
			
			//设置深度
			if(_funcs.length == 0 ) changeDept();
		}
		
		private function onOtherWalking(evt : Event):void
		{
			if(otherWalkArr.length!=0)
			{
				for each(var fun : Function in otherWalkArr)
				{
					//移动
					fun.call();
				}
			}
			
			if(otherWalkArr.length==0) _stage.removeEventListener(Event.ENTER_FRAME, onOtherWalking);
			
			//设置深度
			if(_funcs.length == 0 ) changeDept();
		}
		
		private function onWalkingEx(e:TimerEvent):void
		{
			var tFlag:uint	=	getTimer();
			//			trace(tFlag - _pTimeFlag);
			var playerBg	: Sprite	=	SceneManager.getInstance().norSceneView.playerBG;
			if(tFlag - _pTimeFlag > 1000/_stage.frameRate && playerBg.numChildren >= controlNum -5)
			{
				needSpeed	=	true;
				_stage.addEventListener(Event.ENTER_FRAME, onWalking);
			}
			else
			{
				needSpeed		=	false;
			}
			
			if(tFlag - _pTimeFlag > _tDelay)//
			{
				if(_funcs.length!=0)
				{
					for each(var func : Function in _funcs)
					{
						//移动
						func.call();
					}
					e.updateAfterEvent();
				}
				else if(_funcs.length ==0)
				{
					removeRenderEvent();
				}
				
				_pTimeFlag	=	tFlag;
			}
		}
		
		private function onWalkingOther(e:TimerEvent):void
		{
			var tFlag:uint	=	getTimer();
			if(tFlag - pTimeFlag > _tDelay)//
			{
				if(otherWalkArr.length!=0)
				{
					for each(var fun : Function in otherWalkArr)
					{
						//移动
						fun.call();
					}
				}
				pTimeFlag	=	tFlag;
			}
		}
		
		private function checkEvent(evt : Event):void
		{
			//设置深度
			changeDept()
		}
		
		public function addWalkFunc(func : Function):void
		{
			if(-1 != _funcs.indexOf(func))
			{
				return;
			}
			
			_funcs.push(func);
			addRenderEvent();
		}
		
		public function addOtherWalkFunc(func : Function):void
		{
			if(-1 != otherWalkArr.indexOf(func))
			{
				return;
			}
			
			otherWalkArr.push(func);
			addOtherRenderEvent();
		}
		
		public function delWalkFunc(func : Function):void
		{
			var index : int = _funcs.indexOf(func);
			if(-1 != index)
			{
				_funcs.splice(index, 1);
			}
			if(_funcs.length == 0)
			{
				removeRenderEvent();
			}
		}
		
		public function delOtherWalkFunc(func : Function):void
		{
			var otherIndex : int = otherWalkArr.indexOf(func);
			if(-1 != otherIndex)
			{
				otherWalkArr.splice(otherIndex, 1);
			}
			
			if(otherWalkArr.length == 0)
			{
				removeOtherRenderEvent();
			}
		}
		
		public function clear():void
		{
			_funcs = [];
			
			otherWalkArr = [];
			
			removeRenderEvent()
		}
		private function beforehandLoad():void
		{
			if(GameData.SceneType == GameDefine.SceneType_WorldBossScene)
				return;
			isShowLoading=true;
			MiniLoadingBar.getInstance().show("预加载中....");
			_showTimer.start();
			//			MiniLoadingBar.getInstance().progress =53/100;
		}
		private function onPlay(e:TimerEvent):void
		{
			if(isShowLoading)
			{
				if(_showTimer.currentCount<100)
					MiniLoadingBar.getInstance().progress =_showTimer.currentCount/100;
			}
			else
			{
				_showTimer.reset();
			}
			
		}
		private function encounterMonster( players : Array ):void
		{
			ArrowGuideLogic.getInstance().hideArrow();
			
			if( Fight || SceneType == GameDefine.SceneType_Normal || !SceneManager.getInstance().norSceneView.visible 
				|| Role == null || Role.playerObj == null || Role.playerObj.GetPropertiesEx( "CanFight" ) == 1 )
			{
				return;
			}
			
			var player : BasePlayerModel;
			
			if(SceneType == GameDefine.SceneType_CS || SceneType == GameDefine.SceneType_WorldBossScene ||SceneType ==	GameDefine.SceneType_FactionBossScene)
			{
				//剧情中不遇怪
				if( StoryMoveUI.IsStory )return;
				//当是副本，通过主角判断是否遇怪
				for each( player in players )
				{
					if( player is NpcModel && player.playerObj.Type == ObjType.NPC && player.visible )
					{//是会移动的怪，计算距离
						var dis : int = Point.distance( Role.point, player.point );
						if(dis >= ArrowGuideLogic.getInstance().showGuideDis)
						{
							ArrowGuideLogic.getInstance().showArrow();
						}
						else
						{
							ArrowGuideLogic.getInstance().hideArrow();
						}
						if(dis < 80 )
						{
							if(GameData.EliteFBScene ==GameDefine.SceneElite_FbScene) //经营副本
							{
								WarfareLogic.getInstance().enable=false;
								if(WarfareLogic.getInstance().isClick)
								{
									player.killMove();
									GameData.Role.killMove();
									return;
								}
							}
							
							if(isFight)	return;
							
							//							beforehandLoad();
							SystemSender.getInstance().SelectObjInScene( player.playerObj.ObjID, 1 );
							( player as NpcModel ).removeFacePoPo();
						}
						else if(dis >= 400 && dis < 500 && SceneType == GameDefine.SceneType_CS)
						{
							(player as NpcModel).addFacePoPo();
							player.playerMovie.scaleX = -1;
							player.killMove();
						}
						else if( dis < 400 && SceneType == GameDefine.SceneType_CS )
						{
							
							( player as NpcModel ).npcautoMove( Role.point );
							
							
						}else if( dis > 500 && SceneType == GameDefine.SceneType_CS )
						{
							( player as NpcModel ).resetPoint();
							
							if(player.status == PlayerActionFlag.Wait)
							{
								( player as NpcModel ).boosMove();
							}
							( player as NpcModel ).removeFacePoPo();
						}
					}
				}
			}
			else if(SceneType == GameDefine.SceneType_SnowBallFightScene)
			{
				for each( player in players )
				{
					if( player is NpcModel && player.visible && player.playerObj.Type == ObjType.NPC )
					{
						if(Point.distance( Role.point, player.point) < 80 )
						{
							if(MakeSnowLogic.getInstance().isShow) MakeSnowLogic.getInstance().stopMake();
							isFight	=	true;
							SystemSender.getInstance().SelectObjInScene( player.playerObj.ObjID, 1 );
						}
					}
				}
			}
			else if( SceneType == GameDefine.SceneType_FactionScene )
			{
				for each( player in players )
				{
					if( player is PlayerModel && player.visible && !( player is RoleModel ) )
					{//是会移动的怪，计算距离
						if(FactionAttackLogic.getInstance().BattleState == false) return;
						if(  Point.distance( Role.point, player.point ) < 20 )
						{
							_txt.htmlText = player.playerName
							var name:String =_txt.text;
							SystemSender.getInstance().CustomMsg(
								CustomToServerFlag.CLIENT_CUSTOMMSG_PK, new WString( name) );	
							//							SystemSender.getInstance().SelectObjInScene( player.playerObj.ObjID, 1 );
							return;
						}
					}
				}
			}
			else if( SceneType == GameDefine.SceneType_ForbiddenAreaScene )
			{
				for each( player in players )
				{
					if( player is NpcModel && player.visible && !( player is RoleModel ) )
					{//是会移动的怪，计算距离
						var rect:Rectangle	=	(player as NpcModel).moveRect;
						var _cellSize:int	=	ForbiddenAreaLogic.getInstance()._cellSize;
						var point:Point		=	Role.point;
						if(rect!=null)
						{
							if( point.x>=rect.x-15 && point.x<=rect.x+rect.width+15 && point.y>=rect.y-15 && point.y<=rect.y+rect.height+15 )
							{
								clearInterval(ForbiddenAreaLogic.getInstance().stepIndex);
								GameData.Role.killMove();
								(player as NpcModel).npcautoMove(point);
							}
						}
						if(  Point.distance( Role.point, player.point ) < 40 )
						{
							if(_isReset) return;
							var objPoint:Point = player.playerObj.ObjID;
							SystemSender.getInstance().CustomMsg(
								CustomToServerFlag.CLIENT_CUSTOMMSG_FORBID_NPC_SELECT, objPoint );
							clearInterval(ForbiddenAreaLogic.getInstance().stepIndex);
							GameData.Role.status	=	PlayerActionFlag.NormalWait;
							player.moveLogic.speed	=	NpcModel.moveSpeed;
							_isReset	=	true;
							return;
						}
						
					}
				}
			}
			
			
		}
		
		public function get isFight():Boolean
		{
			return isFightPre;
		}
		
		public function set isFight(val:Boolean):void
		{
			isFightPre	=	val;
		}
		
		public function changeDept():void
		{	
			var playerBg	: Sprite	=	SceneManager.getInstance().norSceneView.playerBG;
			
			var depthArray 	: Array 	=	[];
			for(var i:int; i < playerBg.numChildren ; i ++)
			{
				depthArray.push(playerBg.getChildAt(i) as Sprite);
			}
			
			if( depthArray.length == 0 ) return;
			
			
			encounterMonster( depthArray );
			
			depthArray.sortOn( [ "y","name" ], [Array.NUMERIC,Array.CASEINSENSITIVE]);
			
			var j : int	=	depthArray.length;
			
			var tpMc	:	Sprite;
			
			while ( --j >= 0 )
			{
				tpMc 	=	depthArray[ j ] as Sprite;
				
				if( tpMc.parent && tpMc.visible)
				{
					if( tpMc.parent.getChildIndex( tpMc ) == j )
					{
						continue;
					}
					tpMc.parent.setChildIndex( tpMc, j );
				}
			}
		}
		
		public function set moveTimer(value:Timer):void
		{
			var isWalk : Boolean = _isWalk;
			
			if( isWalk )
			{
				removeRenderEvent();
			}
			
			_moveTimer = value;
			
			if( isWalk )
			{
				addRenderEvent();
			}
			
		}
	}
}